#ifndef     __HANDLER_H
#define     __HANDLER_H

#include <memory>

struct Handler {

    virtual void exec() = 0;
    virtual ~Handler() {}
};

template <typename F>
struct HandlerImpl : public Handler {

public:
    HandlerImpl(F&& f) : m_func(std::move(f)) {}

    void exec() override {
        m_func();
    }

private:
    F m_func;
};

using HandlerPtr = std::unique_ptr<Handler>;

template <typename F>
concept HandlerTrait = requires(F f) {
    { f() } ;
};

template <HandlerTrait F>
inline HandlerPtr make_handler(F&& f) {
    return std::make_unique<HandlerImpl<F>>(std::move(f));
}

#endif
